import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
const M = 3
// 定义一个组件类
class Square extends React.Component {
  // 通过state记录组件被点击过的状态
  // 在构造函数汇总初始化state
  // 【状态提升到父组件中】
  // constructor(props) {
  //   // 子类构造函数中必须以super开头
  //   super(props);
  //   this.state = {
  //     value: null
  //   };
  // }
  // 组件参数为props
  // render返回需要展示的视图的层次结构
  render() {
    // 返回一个React元素 对渲染内容的轻量级描述
    let color = this.props.color
    return (
      // JSX语法 会被编译为React.createElement('button')
      // 绑定click事件
      // 为了减少输入和this的困扰 使用箭头函数处理
      <button 
        className={`square ${color === 'red'? 'red':'black'}`} 
        onClick={() => {this.props.onClick()}}
      >
        {/* 大括号包裹JS表达式 */}
        {/* 通过props获取父组件Board中传递过来的参数i */}
        {this.props.value}
      </button>
    );
  }
}
// 渲染9个子组件Square
// 状态提升：需要获取多个子组件数组或者需要组件通信的时候，
// 需要把子组件的state数据提升到父组件中保存，之后父组件通过props传递数组到子组件
class Board extends React.Component {
  // constructor(props) {
  //   super(props);
  //   // 数据私有 向子组件传递一个函数，处理对数据的操作
  //   this.state = {
  //     square: Array(9).fill(null), 
  //     xIsNext: true,
  //   }
  // }
  renderSquare(i) {
    let color;
    if (this.props.lines && this.props.lines.includes(i)) {
      color = 'red';
    } else {
      color = 'black';
    }
    // 通过props.value传递参数
    // return拆分为多行 加上小括号
    return (
      <Square
        key={i}
        color={color}
        value={this.props.squares[i]}
        onClick={() => this.props.onClick(i)}
      />
    );
  }

  render() {
    // let status
    // const winner = calculateWinner(this.state.square);
    // if (winner) {
    //   status = 'Winner：' + winner;
    // } else {
    //   status = 'Next player: ' + (this.state.xIsNext? 'X':'O');
    // }
    return (
      <div>
        {(() => {
          let domArr = []
          for(let i = 0; i < M; i++) {
            let subArr = []
            for (let j = 0; j < M; j++) {
              subArr.push(this.renderSquare(i * M + j))
            }
            domArr.push(
              <div className="board-row" key={i}>
                {subArr}
              </div>
            )
          }
          return domArr
        })()}
        {/* <div className="status">{status}</div> */}
        {/* <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div> */}
      </div>
    );
  }
}
// 渲染棋盘
// 历史记录列表展示在Game组件中，将history提升到Game中
class Game extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      history: [{
        squares: Array(M * M).fill(null)
      }],
      xyHistory: [{
        xy: Array(2).fill(null)
      }],
      stepNumber: 0,
      xIsNext: true,
      order: true,
      orderDesc: '降序'
    }
  }
  handleClick(i) {
    // 移除回退的历史记录
    const history = this.state.history.slice(0, this.state.stepNumber + 1);
    const xyHistory = this.state.xyHistory.slice(0, this.state.stepNumber + 1);
    const current = history[history.length-1];
    // 不可变性：拷贝square
    const squares = current.squares.slice();
    if (calculateWinner(squares).winner || squares[i]) {
      return;
    }
    this.setState({xyHistory: xyHistory.concat([{xy: [Math.floor(i/3), i%3]}])});
    squares[i] = this.state.xIsNext? 'X':'O';
    this.setState({
      history: history.concat([{
        squares: squares
      }]),
      stepNumber: history.length,
      xIsNext: !this.state.xIsNext,
    });
  }
  jumpTo(step) {
    this.setState({
      stepNumber: step,
      xIsNext: (step % 2) === 0,
      status: ''
    });
  }
  changeOrder() {
    this.setState({
      order: !this.state.order,
      orderDesc: this.state.order?'升序':'降序'
    })
  }
  render() {
    const history = this.state.history;
    const xyHistory = this.state.xyHistory;
    const current = history[this.state.stepNumber];
    const curNumber = this.state.stepNumber
    const result = calculateWinner(current.squares);
    const winner = result.winner
    const lines = result.lines
    // 将历史步骤映射为代表按钮的react元素
    const moves = history.map((step, move) => {
      const desc = move ? 
        'Go to move #' + move + ' position is: (' + xyHistory[move].xy + ')':
        'Go to game start';
      return (
        <li key={move}>
          <button  className={move === curNumber?'boldbutton button': 'button'} onClick={() => this.jumpTo(move)}>{desc}</button>
        </li>
      )
    })
    let movesOrder
    if (this.state.order) {
      movesOrder = moves
    } else {
      movesOrder = moves.reverse()
    }
    let status
    if (winner) {
      status = 'Winner:' + winner
    }
    else if (!winner && this.state.stepNumber === M * M) {
      status = 'No Winner!'
    } 
    else {
      status = 'Next player: ' + (this.state.xIsNext? 'X':'O');
    }
    return (
      <div className="game">
        <div className="game-board">
          {/* 将获胜的线传入Board */}
          <Board
            lines={lines}
            squares={current.squares}
            onClick={(i) => this.handleClick(i)}
          />
        </div>
        <div className="game-info">
          <button className="button" onClick={() => this.changeOrder()}>{this.state.orderDesc}</button>
          <div>{status}</div>
          <div>{this.state.status}</div>
          <ol>{movesOrder}</ol>
        </div>
      </div>
    );
  }
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

// 判断胜方
function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ]
  for(let i = 0; i < lines.length; i++) {
    // 如果线上的元素都是O或者都是X 就返回这个元素
    const [a, b, c] = lines[i]
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      console.log(squares[a],squares[b],squares[c]);
      // 修改返回值 返回具体呈现的是哪一条线
      // return squares[a]
      return {winner: squares[a], lines: lines[i]}
    }
  }
  return {winner: null, lines: null}
}
